
/**
 * @file h5_factory_test.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "h5_factory_test.h"
#include "lv_100ask_boot_animation.h"

#include "fdcan.h"
#include "usart.h"
#include "driver_usart.h"
#include "driver_fdcan.h"
#include "at_command.h"

#include "lvgl.h"

#include "config.h"

/*********************
 *      DEFINES
 *********************/
#define  BOOT_ANIMATION_TIME  600

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_timer_t * creat_test_item(lv_obj_t * parent, char * str_left, char * str_mid, char * str_right);
static void test_item_timer(lv_timer_t * timer);
static void boot_after_init_timer(lv_timer_t * t);

static void get_chipUID(lv_obj_t * label);

static int ch1_485_to_ch2_485_test(void);
static int ch2_485_to_ch1_485_test(void);
static int ch1_can_to_ch2_can_test(void);
static int ch2_can_to_ch1_can_test(void);
static int at_test(void);

static void drag_event_handler(lv_event_t * e);


/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
void h5_factory_test(void)
{
	lv_100ask_boot_animation(BOOT_ANIMATION_TIME);
	
	lv_timer_t * timer = lv_timer_create(boot_after_init_timer, BOOT_ANIMATION_TIME + 20, NULL);
	lv_timer_set_repeat_count(timer, 1);
	
}

static void boot_after_init_timer(lv_timer_t * t)
{
	lv_timer_t * timer;

	lv_obj_t * panel_main = lv_obj_create(lv_scr_act());
	lv_obj_remove_style_all(panel_main);
	lv_obj_set_size(panel_main, LV_PCT(100), LV_PCT(100));    
	lv_obj_set_flex_flow(panel_main, LV_FLEX_FLOW_COLUMN);
	lv_obj_set_flex_align(panel_main, LV_FLEX_ALIGN_SPACE_AROUND, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
	
	LV_IMG_DECLARE(img_lv_100ask_demo_logo);
	lv_obj_t * logo = lv_img_create(panel_main);
	lv_img_set_src(logo, &img_lv_100ask_demo_logo);
	//lv_img_set_zoom(logo, 512);

	creat_test_item(panel_main, "CH1-485", LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_RIGHT, "CH2-485");
	creat_test_item(panel_main, "CH1-485", LV_SYMBOL_LEFT LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS, "CH2-485");

	timer = creat_test_item(panel_main, "CH1-CAN", LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_RIGHT, "CH2-CAN");
	lv_timer_set_period(timer, 100);
	timer = creat_test_item(panel_main, "CH1-CAN", LV_SYMBOL_LEFT LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS, "CH2-CAN");
	lv_timer_set_period(timer, 100);
	
	creat_test_item(panel_main, "USART1", LV_SYMBOL_LEFT LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_RIGHT, "Wi-Fi chip");
	
	timer = creat_test_item(panel_main, "UID: ", "NULL", " ");
	lv_timer_set_period(timer, 1000);
	
	// drag test
	lv_obj_t * obj;
	obj = lv_obj_create(lv_scr_act());
	lv_obj_set_size(obj, 100, 55);
	lv_obj_add_event_cb(obj, drag_event_handler, LV_EVENT_PRESSING, NULL);

	lv_obj_t * label = lv_label_create(obj);
	lv_label_set_text(label, "Drag me");
	lv_obj_center(label);
}

static lv_timer_t * creat_test_item(lv_obj_t * parent, char * str_left, char * str_mid, char * str_right)
{
    lv_obj_t * cb;
    lv_obj_t * label;

    lv_obj_t * panel_item = lv_obj_create(parent);
    lv_obj_remove_style_all(panel_item);
    lv_obj_set_size(panel_item, LV_PCT(68), LV_SIZE_CONTENT);    
    lv_obj_set_flex_flow(panel_item, LV_FLEX_FLOW_ROW);
    lv_obj_set_flex_align(panel_item, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);

    cb = lv_checkbox_create(panel_item);
    lv_obj_add_state(cb, LV_STATE_DISABLED);
    lv_checkbox_set_text(cb, "");

    label = lv_label_create(panel_item);
    lv_obj_set_style_text_font(label, &lv_font_montserrat_22, 0);
    lv_label_set_text(label, str_left);

    label = lv_label_create(panel_item);
    lv_obj_set_style_text_font(label, &lv_font_montserrat_22, 0);
    lv_label_set_text(label, str_mid);

    label = lv_label_create(panel_item);
    lv_obj_set_style_text_font(label, &lv_font_montserrat_22, 0);
    lv_label_set_text(label, str_right);

    return lv_timer_create(test_item_timer, 20,  panel_item);		
}

static void test_item_timer(lv_timer_t * timer)
{
	/*Use the user_data*/
	lv_obj_t * panel_item = (lv_obj_t *)timer->user_data;

  int res = 0;
	lv_obj_t * cb; 
	lv_obj_t * label1; 
	lv_obj_t * label2; 
	lv_obj_t * label3; 
	
	cb = lv_obj_get_child(panel_item, 0);
	label1 = lv_obj_get_child(panel_item, 1);
	label2 = lv_obj_get_child(panel_item, 2);
	label3 = lv_obj_get_child(panel_item, 3);

	if((strcmp(lv_label_get_text(label1), "CH1-485") == 0) &&\
			(strcmp(lv_label_get_text(label2), LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_RIGHT) == 0) &&\
			(strcmp(lv_label_get_text(label3), "CH2-485") == 0))
			{
					res = ch1_485_to_ch2_485_test();
			}
	else if((strcmp(lv_label_get_text(label1), "CH1-485") == 0) &&\
			(strcmp(lv_label_get_text(label2), LV_SYMBOL_LEFT LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS) == 0) &&\
			(strcmp(lv_label_get_text(label3), "CH2-485") == 0))
			{
					res = ch2_485_to_ch1_485_test();
			}
	else if((strcmp(lv_label_get_text(label1), "CH1-CAN") == 0) &&\
			(strcmp(lv_label_get_text(label2), LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_RIGHT) == 0) &&\
			(strcmp(lv_label_get_text(label3), "CH2-CAN") == 0))
			{
					res = ch1_can_to_ch2_can_test();
			}
	else if((strcmp(lv_label_get_text(label1), "CH1-CAN") == 0) &&\
			(strcmp(lv_label_get_text(label2), LV_SYMBOL_LEFT LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_MINUS) == 0) &&\
			(strcmp(lv_label_get_text(label3), "CH2-CAN") == 0))
			{
					res = ch2_can_to_ch1_can_test();
			}
	else if((strcmp(lv_label_get_text(label1), "USART1") == 0) &&\
			(strcmp(lv_label_get_text(label2), LV_SYMBOL_LEFT LV_SYMBOL_MINUS LV_SYMBOL_MINUS LV_SYMBOL_RIGHT) == 0) &&\
			(strcmp(lv_label_get_text(label3), "Wi-Fi chip") == 0))
			{
					res = at_test();
			}
	
	else if((strcmp(lv_label_get_text(label1), "UID: ") == 0))
			{
				lv_obj_add_state(cb, LV_STATE_CHECKED);
				get_chipUID(label2);
			}

	// test pass
	if(res)
	{
		lv_timer_del(timer);
		lv_obj_add_state(cb, LV_STATE_CHECKED);
		lv_obj_set_style_text_color(panel_item, lv_color_hex(0x00ff00), 0);
	}

}

static int ch485_get_rx(UART_HandleTypeDef *huart, uint8_t *pcRecvBuf, uint16_t rc_buf_len, int iTimeoutMS)
{
	ring_buffer *uart_ringbuffer = NULL;
	uint8_t *buf = pcRecvBuf;
	int i = 0;
	int pre;
	int now;
	
	if(huart == &huart2)	uart_ringbuffer = &g_usart2_ring_buffer;
	else if(huart == &huart4)	uart_ringbuffer = &g_usart4_ring_buffer;

	pre = HAL_GetTick();
	while (iTimeoutMS)
	{
		if(i >= rc_buf_len) break;
		if (ring_buffer_read(&buf[i], uart_ringbuffer) == 0)
		{
			i++;
		}
		
		now = HAL_GetTick();
		if (now > pre)
		{
			iTimeoutMS--;
			pre = now;
		}
		
	}
	return i;
}


static int ch1_485_to_ch2_485_test(void)
{
	int res = 0;
	
	uint16_t count = 0;
	uint8_t str_test[23] = "https://www.100ask.net";
	uint8_t str_buf[23] = {0};

	ring_buffer_nvalid_buf(&g_usart4_ring_buffer);
	
	USART_SendBytes(&huart2, str_test, 23);
	
	ch485_get_rx(&huart4, str_buf, 23, 5);
	
	if(strcmp((const char *)str_buf, (const char *)str_test) == 0)	res = 1;
	else 	res = 0;
	
	return res;
}

static int ch2_485_to_ch1_485_test(void)
{
	int res = 0;
	
	uint16_t count = 0;
	uint8_t str_test[23] = "https://www.100ask.net";
	uint8_t str_buf[23] = {0};
	
	ring_buffer_nvalid_buf(&g_usart2_ring_buffer);
	USART_SendBytes(&huart4, str_test, 23);
	
	ch485_get_rx(&huart2, str_buf, 23, 5);
	
	if(strcmp((const char *)str_buf, (const char *)str_test) == 0)	res = 1;
	else 	res = 0;
	
	return res;
}


static int ch1_can_to_ch2_can_test(void)
{
	int res = 0;

	/* Add message to TX FIFO of FDCAN instance 1 */
	if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
	{
		debug_printf("hfdcan1 send error!\r\n");
	}
	else debug_printf("hfdcan1 send Message Successfully!\r\n");

	if(can2flag == 1)
	{
		can2flag = 0;
		if(strcmp((const char *)RxData, (const char *)TxData) == 0)	res = 1;
		else res = 0;
		
		memset(RxData, 0, 16);
	}
	
	return res;
}

static int ch2_can_to_ch1_can_test(void)
{
	int res = 0;

	/* Add message to TX FIFO of FDCAN instance 1 */
	if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TxHeader, TxData) != HAL_OK)
	{
		debug_printf("hfdcan1 send error!\r\n");
	}
	else debug_printf("hfdcan1 send Message Successfully!\r\n");

	if(can1flag == 1)
	{
		can1flag = 0;
		if(strcmp((const char *)RxData, (const char *)TxData) == 0)	res = 1;
		else res = 0;
		
		memset(RxData, 0, 16);
	}
	
	return res;
}

static int at_test(void) 
{
	int res = 0;
	
	uint8_t str_atcmd[] = "AT+\n";
	uint8_t buf [32] = {0};

	ATCommandSendAndRecv(str_atcmd, buf, 1000);
	
	if(strcmp((const char *)buf, "+OK\r\n") == 0)	res = 1;
	//if(strstr((const char *)buf, "OK"))	res = 1;
	else res = 0;

	return res;
}


/* get chip UID */

static void get_chipUID(lv_obj_t * label)
{
	uint32_t UIDw[3];
	
	UIDw[0] = HAL_GetUIDw0();
  UIDw[1] = HAL_GetUIDw1();
  UIDw[2] = HAL_GetUIDw2();

	lv_obj_set_style_text_font(label, &lv_font_montserrat_16, 0);
	lv_label_set_text_fmt(label, "%08X-%08X-%08X", UIDw[0], UIDw[1], UIDw[2]);
	
	debug_printf("%08X-%08X-%08X\r\n", UIDw[0], UIDw[1], UIDw[2]);
}



static void drag_event_handler(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);

    lv_indev_t * indev = lv_indev_get_act();
    if(indev == NULL)  return;

    lv_point_t vect;
    lv_indev_get_vect(indev, &vect);

    lv_coord_t x = lv_obj_get_x(obj) + vect.x;
    lv_coord_t y = lv_obj_get_y(obj) + vect.y;
    lv_obj_set_pos(obj, x, y);
}


